home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 1 Issue 2 / PDCD-1 - Issue 02.iso / _utilities / utilities / 003 / motorola / Sources / c / ifd < prev    next >
Text File  |  1993-07-18  |  13KB  |  277 lines

  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4.  
  5. #include "mselect.h"    /*external selection of microprocessor symbol table*/
  6. #include "proto.h"
  7. #include "as.h"
  8. #include "extvars.h"
  9. #include "structs.h"
  10.  
  11.  
  12. /*
  13.  * IfMachine() --- This function implements the IFD & IFND conditional
  14.  * assembly machine. version 1.0 made for release TER_2.0 cross assembler 27
  15.  * Jun 89
  16.  */
  17.  
  18. #define FALSE_BLOCK     0       /* values for state variable */
  19. #define TRUE_BLOCK      1
  20. #define POP_TEST        2
  21. #define ELSE_TEST       3
  22. #define FALSE           0
  23. #define TRUE            1
  24.  
  25. void
  26. IfMachine(int Token)
  27. /* input token from calling machine */
  28. /* See file as.h for definition (globals) */
  29. {
  30.         static int      State = TRUE_BLOCK, StackPt = 0, IfStack[MAXIFD];
  31.         /* State variable, pointer to "IF stack pointer" and "Stack" */
  32.         int             Hiatus; /* flag to break out of FSM & resume normal
  33.                                  * processing */
  34.  
  35.         Hiatus = FALSE;         /* infinite loop to operate machine until
  36.                                  * time to break out */
  37.         do {                    /* test at end */
  38.  
  39. #ifdef DEBUG3
  40.                 printf("IfMachine state=%u , token=%u\n", State, Token);
  41. #endif
  42.  
  43.                 if (State == TRUE_BLOCK)        /* a block of statements
  44.                                                  * processed normally */
  45.                         switch (Token) {
  46.                         case IF_TRUE:
  47.                                 IfStack[StackPt] = TRUE;
  48.                                 if (++StackPt > MAXIFD) {       /* check for over flow */
  49.                                         StackPt = MAXIFD;
  50.                                         error("Error:IFD/IFND nested too deep");
  51.                                 }
  52.                                 /*
  53.                                  * print_line() will be done in normal
  54.                                  * processing
  55.                                  */
  56.                                 Hiatus = TRUE;  /* resume normal line
  57.                                                  * processing */
  58.                                 break;
  59.                         case IF_FALSE:
  60.                                 IfStack[StackPt] = TRUE;
  61.                                 if (++StackPt > MAXIFD) {       /* check for over flow */
  62.                                         StackPt = MAXIFD;
  63.                                         error("Error:IFD/IFND nested too deep");
  64.                                 }
  65.                                 if (Pass == 2 && Lflag && !N_page)      /* need to print here */
  66.                                         print_line();   /* cuz will not return
  67.                                                          * to normal */
  68.                                 Token = GetToken();     /* get next line &
  69.                                                          * examine for IF */
  70.                                 State = FALSE_BLOCK;    /* change state */
  71.                                 break;
  72.                         case IF_ELSE:
  73.                                 if (StackPt == 0)       /* bad IF nesting */
  74.                                         error("Error: ELSE without IF");
  75.                                 if (Pass == 2 && Lflag && !N_page)
  76.                                         print_line();
  77.                                 Token = GetToken();     /* get next line &
  78.                                                          * examine for IF */
  79.                                 State = FALSE_BLOCK;
  80.                                 break;
  81.                         case IF_ENDIF:
  82.                                 if (StackPt == 0)       /* bad IF nesting */
  83.                                         error("Error: ENDIF without IF");
  84.                                 else
  85.                                         StackPt--;      /* popped state must be
  86.                                                          * TRUE */
  87.                                 Hiatus = TRUE;
  88.                                 break;
  89.                                 /*
  90.                                  * case NORMAL is not implemented as it
  91.                                  * represents normal line processing.
  92.                                  */
  93.                         case IF_END:    /* file ended with improperly nested
  94.                                          * IFD */
  95.                                 /*
  96.                                  * this code can't actually be reached at
  97.                                  * present in a TRUE_BLOCK
  98.                                  */
  99.                                 fatal("Error: file ended before IFD/IFND/ELSE/ENDIF");
  100.                                 break;
  101.                         default:        /* This code can't be reached at the
  102.                                          * present. Logically would happen if
  103.                                          * EOF but handled else where */
  104.                                 fatal("Can't get here from there.");
  105.                                 break;
  106.                         }
  107.                 else if (State == FALSE_BLOCK)  /* statements not processed */
  108.                         switch (Token) {
  109.                         case IF_TRUE:   /* doesn't make any diff. Just nest
  110.                                          * IFs */
  111.                         case IF_FALSE:
  112.                                 IfStack[StackPt] = FALSE;
  113.                                 if (++StackPt > MAXIFD) {
  114.                                         StackPt = MAXIFD;
  115.                                         error("Error:IFD/IFND nested too deep");
  116.                                 }
  117.                                 if (Pass == 2 && Lflag && !N_page)
  118.                                         print_line();
  119.                                 Token = GetToken();
  120.                                 break;
  121.                         case IF_ELSE:
  122.                                 if (Pass == 2 && Lflag && !N_page)
  123.                                         print_line();
  124.                                 State = ELSE_TEST;
  125.                                 break;
  126.                         case IF_ENDIF:
  127.                                 State = POP_TEST;
  128.                                 break;
  129.                         case IF_END:    /* file ended with improperly nested
  130.                                          * IFD */
  131.                                 fatal("Fatal Error: file ended before last ENDIF");
  132.                                 /*
  133.                                  * Fatal will exit assembler.  Things are too
  134.                                  * messed up.  Include file handling is else
  135.                                  * where and don't want to duplicate here.
  136.                                  */
  137.                                 break;
  138.                         case IF_NORMAL: /* normal line in a FALSE
  139.                                                  * BLOCK */
  140.                                 if (Pass == 2 && Lflag && !N_page)
  141.                                         print_line();
  142.                                 Token = GetToken();
  143.                                 break;
  144.                         default:
  145.                                 fatal("Fatal Error: file ended before last ENDIF");
  146.                                 /* must be EOF or something else terrible */
  147.                                 break;
  148.                         }
  149.                 else if (State == POP_TEST) {   /* pop up outside nest state */
  150.                         if (StackPt == 0) {     /* bad IF nesting */
  151.                                 error("Error: ENDIF without IF");
  152.                                 if (Pass == 2 && Lflag && !N_page)
  153.                                         print_line();
  154.                                 State = TRUE;
  155.                         } else {
  156.                                 StackPt--;      /* pop stack */
  157.                                 if (IfStack[StackPt] == TRUE) { /* back to normal */
  158.                                         /*
  159.                                          * had to come from FALSE block cuz
  160.                                          * TRUE block cannot be inside FALSE
  161.                                          * block
  162.                                          */
  163.                                         if (Pass == 2 && Lflag && !N_page)
  164.                                                 print_line();
  165.                                         State = TRUE;
  166.                                         Hiatus = TRUE;  /* sleep for normal line
  167.                                                          * processing */
  168.                                 } else {        /* gotta be that stack ==
  169.                                                  * FALSE, still inside FALSE
  170.                                                  * nest */
  171.                                         if (Pass == 2 && Lflag && !N_page)
  172.                                                 print_line();
  173.                                         State = FALSE;
  174.                                         Token = GetToken();
  175.                                 }
  176.                         }
  177.                 } else if (State == ELSE_TEST) {        /* change state */
  178.                         if (IfStack[StackPt - 1] == TRUE) {
  179.                                 State = TRUE_BLOCK;
  180.                                 Hiatus = TRUE;
  181.                         } else
  182.                                 State = FALSE_BLOCK;
  183.                 }
  184.         }
  185.         while (Hiatus == FALSE);/* loop if not exit */
  186. }
  187.  
  188.  
  189. /*
  190.  * GetToken() --- get another line from within False Block and extract token
  191.  * as would be done in pseudo.c.  Returns token id: IF_TRUE         IFD/IFND
  192.  * evaluated to TRUE IF_FALSE        IFD/IFND evaluated to FALSE IF_ELSE ELSE
  193.  * pseudo op IF_ENDIF        ENDIF pseudo op IF_END          END pseudo op
  194.  * IF_NORMAL       none of the above, perhaps assy code IF_EOF encountered
  195.  * end of file This function exists because conditional assembly was added as
  196.  * pseudo op rather than with key character ("%") and did not want to disturb
  197.  * original software topology
  198.  */
  199.  
  200. int
  201. GetToken(void)
  202. {                               /* get another line and find token in it *//* s
  203.                                  * imilar to make_pass() except one line at a
  204.                                  * time */
  205.         /* most variables & constants are global */
  206.  
  207.         /* struct nlist *lookup(); */
  208.  
  209.         if (FGETS(Line, MAXBUF - 1, Fd) == (char *) NULL)
  210.                 return (IF_EOF);/* banged into eof */
  211.         Line_num++;
  212.         P_force = 0;
  213.         N_page = 0;
  214.         if (!parse_line())
  215.                 return (IF_NORMAL);     /* comment line */
  216.         if (*Op == EOS)         /* skipping over label, probably. */
  217.                 return (IF_NORMAL);     /* strcmp() returns 0 if arg1 is NULL
  218.                                          * string */
  219.  
  220.         if (strcmp(Op, "ifd") == 0)
  221.                 return (eval_ifd());
  222.         else if (strcmp(Op, "ifnd") == 0)
  223.                 return (eval_ifnd());
  224.         else if (strcmp(Op, "else") == 0)
  225.                 return (IF_ELSE);
  226.         else if (strcmp(Op, "endif") == 0)
  227.                 return (IF_ENDIF);
  228.         else if (strcmp(Op, "end") == 0)
  229.                 return (IF_END);
  230.         else
  231.                 return (IF_NORMAL);     /* or might be garbage...but who
  232.                                          * cares? This is FALSE BLOCK */
  233. }
  234.  
  235.  
  236. /*
  237.  * eval_ifd() --- evaluate an if define statement for TRUE or FALSE
  238.  */
  239.  
  240. int
  241. eval_ifd(void)
  242. {
  243.         struct nlist   *np;     /* symbol structure */
  244.  
  245.         if (*Operand == EOS) {
  246.                 warn("No symbol for IFD");
  247.                 return (IF_FALSE);      /* nothing to check */
  248.         }
  249.         if ((np = lookup(Operand)) == NULL)
  250.                 return (IF_FALSE);      /* not defined at all...yet */
  251.         else if (np->def2 == Pass)
  252.                 return (IF_TRUE);       /* defined for this pass */
  253.  
  254.         return (IF_FALSE);      /* not defined this pass */
  255. }
  256.  
  257. /*
  258.  * eval_ifnd() --- evaluate an if not define statement for TRUE or FALSE
  259.  */
  260.  
  261. int
  262. eval_ifnd(void)
  263. {
  264.         struct nlist   *np;     /* symbol structure */
  265.  
  266.         if (*Operand == EOS) {
  267.                 warn("No symbol for IFND");
  268.                 return (IF_TRUE);       /* nothing to check */
  269.         }
  270.         if ((np = lookup(Operand)) == NULL)
  271.                 return (IF_TRUE);       /* not defined at all...yet */
  272.         else if (np->def2 == Pass)
  273.                 return (IF_FALSE);      /* defined for this pass */
  274.  
  275.         return (IF_TRUE);       /* not defined this pass */
  276. }
  277.